package crawler.web.engine.custom;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import crawler.web.beans.ProxySetting;
import crawler.web.framework.Crawler;

/**
 * @author waynechen Mar 10, 2012 11:45:45 AM
 */
@Component(value = "ProxyDistributor")
public class ProxyDistributor {

	@Autowired(required = true)
	public ProxyDistributor(@Value("#{T(crawler.web.engine.config.ConfigBatchInit).getProxyList()}") LinkedList<ProxySetting> pr) {
		if (pr == null)
			return;
		for (ProxySetting ps : pr) {
			ProxyPac proxyPac = new ProxyPac();
			proxyPac.ps = ps;
			proxys.add(proxyPac);
		}
	}

	private Set<ProxyPac> proxys = new HashSet<ProxyPac>();
	private Map<Crawler, ProxyPac> filter = new HashMap<Crawler, ProxyPac>();

	public synchronized ProxySetting getProxy(Crawler c) {
		if (filter.containsKey(c))
			return filter.get(c).ps;

		Iterator<ProxyPac> it = proxys.iterator();
		if (!it.hasNext())
			return null;
		ProxyPac min, curr;
		min = it.next();
		while (it.hasNext()) {
			curr = it.next();
			if (min.crawlers.size() > curr.crawlers.size())
				min = curr;
		}
		min.crawlers.add(c);

		filter.put(c, min);
		return min.ps;
	}

	public synchronized void releaseProxy(Crawler c) {
		ProxyPac pac = filter.get(c);
		if (pac != null) {
			pac.crawlers.remove(c);
			filter.remove(c);
		}
	}

	private static class ProxyPac {
		public ProxySetting ps = null;
		public Set<Crawler> crawlers = new HashSet<Crawler>();
	}
}
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
